import json
import time
import requests
import golib_cookie
import keep_session
import websocket
import threading
import re

cookieStr = ''

seat_key = ''
lib_id = ''

queue_header = {
    'Host': 'wechat.v2.traceint.com',
    'Connection': 'Upgrade',
    'Pragma': 'no-cache',
    'Cache-Control': 'no-cache',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
                  'Chrome/98.0.4758.102 Safari/537.36 NetType/WIFI MicroMessenger/7.0.20.1781(0x6700143B) '
                  'WindowsWechat(0x63090551) XWEB/6945 Flue',
    'Upgrade': 'websocket',
    'Origin': 'https://web.traceint.com',
    'Sec-WebSocket-Version': '13',
    'Accept-Encoding': 'gzip, deflate, br',
    'Accept-Language': 'zh-CN,zh',
    'Sec-WebSocket-Key': 'eTYh3AZI8PuXyuPRr65Zbg==',
    'Sec-WebSocket-Extensions': 'permessage-deflate; client_max_window_bits',
    'Cookie': cookieStr
}

pre_header = {
    'Host': 'wechat.v2.traceint.com',
    'Connection': 'keep-alive',
    'Content-Length': '310',
    'App-Version': '2.1.1',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
                  'Chrome/98.0.4758.102 Safari/537.36 NetType/WIFI MicroMessenger/7.0.20.1781(0x6700143B) '
                  'WindowsWechat(0x6309001c) XWEB/6763',
    'Content-Type': 'application/json',
    'Accept': '*/*',
    'Origin': 'https://web.traceint.com',
    'Sec-Fetch-Site': 'same-site',
    'Sec-Fetch-Mode': 'cors',
    'Sec-Fetch-Dest': 'empty',
    'Referer': 'https://web.traceint.com/',
    'Accept-Encoding': 'gzip, deflate, br',
    'Accept-Language': 'zh-CN,zh;q=0.9',
    'Cookie': cookieStr
}

preCheck_header = {
    'Host': 'wechat.v2.traceint.com',
    'Connection': 'keep-alive',
    'Content-Length': '195',
    'App-Version': '2.1.1',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 '
                  'Safari/537.36 NetType/WIFI MicroMessenger/7.0.20.1781(0x6700143B) WindowsWechat(0x6309080b) '
                  'XWEB/8461 Flue',
    'Accept': '*/*',
    'Origin': 'https://web.traceint.com',
    'Sec-Fetch-Site': 'same-site',
    'Sec-Fetch-Mode': 'cors',
    'Sec-Fetch-Dest': 'empty',
    'Referer': 'https://web.traceint.com/',
    'Accept-Encoding': 'gzip, deflate, br',
    'Accept-Language': 'zh-CN,zh;q=0.9',
    'Cookie': cookieStr
}

# 预约信息
data2 = {"operationName": "prereserve",
         "query": "query prereserve {\n userAuth {\n prereserve {\n prereserve {\n day\n lib_id\n seat_key\n "
                  "seat_name\n is_used\n user_mobile\n id\n lib_name\n }\n }\n }\n}"}
# 图书馆布局
data_lib_chosen = {"operationName": "libLayout",
                   "query": "query libLayout($libId: Int!) {\n userAuth {\n prereserve {\n "
                            "libLayout(libId: $libId) {\n max_x\n max_y\n seats_booking\n "
                            "seats_total\n seats_used\n seats {\n key\n name\n seat_status\n "
                            "status\n type\n x\n y\n }\n }\n }\n }\n}",
                   "variables": {"libId": 10073}}

# 选座data key是座位横纵坐标 libid是场所的id 这两个参数很重要
data = {"operationName": "save", "query": "mutation save($key: String!, $libid: Int!, $captchaCode: String, $captcha: "
                                          "String) {\n userAuth {\n prereserve {\n save(key: $key, libId: $libid, "
                                          "captcha: $captcha, captchaCode: $captchaCode)\n }\n }\n}",
        "variables": {"key": seat_key, "libid": lib_id, "captchaCode": "", "captcha": ""}}

preCheck_data = {"operationName": "prereserveCheckMsg",
                 "query": "query prereserveCheckMsg {\n userAuth {\n prereserve {"
                          "\n prereserveCheckMsg\n }\n }\n}"}

url = 'https://wechat.v2.traceint.com/index.php/graphql/'


def update_cookie():
    global queue_header, pre_header, cookieStr
    queue_header["Cookie"] = cookieStr
    pre_header["Cookie"] = cookieStr
    preCheck_header["Cookie"] = cookieStr
    seat_change()


def cookie():
    global cookieStr
    while True:
        choice = input("是否需要重新获取cookie yes/no\n")
        if choice == "yes":
            QRCodeUrl = input("Please enter the URL: ")
            code = golib_cookie.get_code(QRCodeUrl)
            cookieStr = golib_cookie.get_cookie_string(code)
            print("\nCookie string: \n")
            print(cookieStr)
            print("------------------------------")
            break
        elif choice == 'no':
            cookieStr = input("请输入cookie")
            break
        else:
            print("输入不合法\n")
    update_cookie()


def seat_change():
    global seat_key, lib_id, data
    with open('seat_and_lib', 'r') as file:
        lines = [file.readline().strip() for _ in range(2)]

    seat_key_match = re.search(r'"seatKey": "(\d+,\d+)"', lines[0])
    lib_id_match = re.search(r'"libId": (\d+)', lines[1])

    if seat_key_match and lib_id_match:
        seat_key = seat_key_match.group(1)
        lib_id = int(lib_id_match.group(1))

    data["variables"]["key"] = seat_key + "."
    data["variables"]["libid"] = str(lib_id)
    book_seat_in_advance()


def pass_queue():
    global queue_header, pre_header, data2, data_lib_chosen, data, url, preCheck_data, preCheck_header
    print("================================")
    print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time())), "开始排队。。。")
    ws = websocket.WebSocket()

    res1 = requests.post(headers=preCheck_header, data=preCheck_data, url=url)
    print(res1.text.encode("utf-8").decode('unicode_escape'))

    ws.connect("wss://wechat.v2.traceint.com/ws?ns=prereserve/queue", header=queue_header)  # 这里的XXXX和Host内容是一致的

    if ws.connected:
        print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time())), 'test pass queue connect')
        while True:
            ws.send('{"ns":"prereserve/queue","msg":""}')
            a = ws.recv()
            print(a)
            if a.find('u6392') != -1:  # 排队成功返回的第一个字符
                break
            if a.find('u6210') != -1:  # 已经抢座成功的返回
                print("rsp msg:{}".format(json.loads(str(a))))
                time.sleep(0.1)
                break
            # time.sleep(0.01)
        # 关闭连接
        ws.close()
    # time.sleep(0.01)
    print("排队结束。。。")
    print("================================")


def book_seat_in_advance():
    global url, pre_header, data, data2, data_lib_chosen, queue_header, cookieStr
    struct_openTime = "2023-12-22 19:59:58"
    openTime = time.strptime(struct_openTime, "%Y-%m-%d %H:%M:%S")
    openTime = time.mktime(openTime)
    request_cnt = 0
    while True:
        timestamp = time.time()

        # 转换成localtime
        time_local = time.localtime(timestamp)
        # 转换成新的时间格式(2016-05-05 20:28:54)
        dt = time.strftime("%Y-%m-%d %H:%M:%S", time_local)
        print(dt, struct_openTime)
        if time.time() >= openTime:

            print("------------------------------")
            print("ok Try to grab seat!")
            request_cnt += 1
            try:
                pass_queue()
                print('test pass queue ==> ok!')
                # 重要！如果不是放在常用座位，需要先请求对应的阅览室的所有座位，libLayout！！
                requests.post(url=url, headers=pre_header, json=data_lib_chosen)
                # 选座
                res = requests.post(url=url, headers=pre_header, json=data)
                print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time())), 'test request ==> ok!')
                # 预约信息
                text_Res = requests.post(url=url, headers=pre_header, json=data2).text
                text_uni = json.loads(str(text_Res).encode('utf-8').decode('unicode_escape'))
                info = text_uni.get('data', {}).get('userAuth', {}).get('prereserve', {}).get('prereserve')
                print(str(res.text).encode('utf-8').decode('unicode_escape'))
                print(text_uni)

                if info is None:
                    print("座位被占或已满")
                    break
                if str(res.text).count("true") and text_Res.count('user_mobile'):
                    print("******************************")
                    print("恭喜你！预定成功！程序即将结束......")
                    print("******************************\n")
                    break
                else:
                    time.sleep(0.1)
            except Exception as e:
                time.sleep(0.1)
                print(e)
                # print('test Exception continue.')
            # break
            print("------------------------------\n\n")
        if request_cnt >= 10:  # 防止请求过多 被老师XX 所以这里我只敢 “最多” 请求10次
            break
    print("程序结束成功！")
    print("请求次数" + str(request_cnt))
    quit()


def keep_cookie():
    print("执行")
    time.sleep(180)
    global cookieStr
    while True:
        if time.localtime().tm_min % 10 == 8:
            keep_session.keep_cookie(cookieStr)


thread2 = threading.Thread(target=keep_cookie)
thread1 = threading.Thread(target=cookie)
thread1.start()
thread2.start()
